package com.cmict.data.system.service.user;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cmict.data.common.websocket.distribute.MessageDO;
import com.cmict.data.common.websocket.distribute.MessageDistributor;
import com.cmict.data.common.websocket.session.WebSocketSessionStore;
import com.cmict.data.framework.common.enums.CommonStatusEnum;
import com.cmict.data.framework.common.exception.ServiceException;
import com.cmict.data.framework.common.pojo.PageResult;
import com.cmict.data.framework.common.util.collection.CollectionUtils;
import com.cmict.data.framework.common.util.json.JsonUtils;
import com.cmict.data.framework.excel.core.util.ExcelUtils;
import com.cmict.data.framework.security.core.LoginUser;
import com.cmict.data.framework.security.core.util.RSAUtils;
import com.cmict.data.framework.security.core.util.SecurityFrameworkUtils;
import com.cmict.data.infra.api.file.FileApi;
import com.cmict.data.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
import com.cmict.data.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
import com.cmict.data.system.controller.admin.user.vo.user.*;
import com.cmict.data.system.convert.user.UserConvert;
import com.cmict.data.system.dal.dataobject.dept.DeptDO;
import com.cmict.data.system.dal.dataobject.dept.PostDO;
import com.cmict.data.system.dal.dataobject.dept.UserPostDO;
import com.cmict.data.system.dal.dataobject.permission.UserRoleDO;
import com.cmict.data.system.dal.dataobject.user.AdminUserDO;
import com.cmict.data.system.dal.mysql.dept.DeptMapper;
import com.cmict.data.system.dal.mysql.dept.PostMapper;
import com.cmict.data.system.dal.mysql.dept.UserPostMapper;
import com.cmict.data.system.dal.mysql.permission.UserRoleMapper;
import com.cmict.data.system.dal.mysql.user.AdminUserMapper;
import com.cmict.data.system.service.dept.DeptService;
import com.cmict.data.system.service.dept.PostService;
import com.cmict.data.system.service.permission.PermissionService;
import com.cmict.data.system.service.tenant.TenantService;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.cmict.data.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cmict.data.framework.common.util.collection.CollectionUtils.convertList;
import static com.cmict.data.framework.common.util.collection.CollectionUtils.convertSet;
import static com.cmict.data.system.enums.ErrorCodeConstants.*;

/**
 * 后台用户 Service 实现类
 * @author awesome
 */
@Service("adminUserService")
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {

    @Value("${sys.user.init-password:123456}")
    private String userInitPassword;

    @Resource
    private AdminUserMapper userMapper;

    @Resource
    private DeptService deptService;
    @Resource
    private PostService postService;
    @Resource
    private PermissionService permissionService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    @Lazy // 延迟，避免循环依赖报错
    private TenantService tenantService;

    @Resource
    private UserPostMapper userPostMapper;
    @Resource
    private UserRoleMapper userRoleMapper;


    @Resource
    WebSocketSessionStore webSocketSessionStore;

    @Resource
    MessageDistributor messageDistributor;

    @Resource
    private FileApi fileApi;

    @Resource
    private DeptMapper deptMapper;

    @Resource
    private PostMapper postMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createUser(UserCreateReqVO reqVO) {
        checkUserNameRegexp(reqVO.getUsername());
        // 校验账户配合
        tenantService.handleTenantInfo(tenant -> {
            long count = userMapper.selectCount();
            if (count >= tenant.getAccountCount()) {
                throw exception(USER_COUNT_MAX, tenant.getAccountCount());
            }
        });
        // 校验正确性
        checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
                reqVO.getDeptId(), reqVO.getPostIds());
        // 插入用户
        AdminUserDO user = UserConvert.INSTANCE.convert(reqVO);
        user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
        String password = RSAUtils.decrypt(reqVO.getPassword());
        checkUserPassword(password);
        user.setPassword(passwordEncoder.encode(password)); // 加密密码

        userMapper.insert(user);
        // 插入关联岗位
        if (CollectionUtil.isNotEmpty(user.getPostIds())) {
            userPostMapper.insertBatch(convertList(user.getPostIds(),
                    postId -> new UserPostDO().setUserId(user.getId()).setPostId(postId)));
        }
        return user.getId();
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(UserUpdateReqVO reqVO) {
        // admin 用户 只有自己可以修改
        checkAdminUser(reqVO.getId(),null);
        checkUserNameRegexp(reqVO.getUsername());
        // 校验正确性
        checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
                reqVO.getDeptId(), reqVO.getPostIds());
        // 更新用户
        AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO);
        userMapper.updateById(updateObj);
        // 更新岗位
        updateUserPost(reqVO, updateObj);
    }

    private void updateUserPost(UserUpdateReqVO reqVO, AdminUserDO updateObj) {
        Long userId = reqVO.getId();
        Set<Long> dbPostIds = convertSet(userPostMapper.selectListByUserId(userId), UserPostDO::getPostId);
        // 计算新增和删除的岗位编号
        Set<Long> postIds = updateObj.getPostIds();
        Collection<Long> createPostIds = CollUtil.subtract(postIds, dbPostIds);
        Collection<Long> deletePostIds = CollUtil.subtract(dbPostIds, postIds);
        // 执行新增和删除。对于已经授权的菜单，不用做任何处理
        if (!CollectionUtil.isEmpty(createPostIds)) {
            userPostMapper.insertBatch(convertList(createPostIds,
                    postId -> new UserPostDO().setUserId(userId).setPostId(postId)));
        }
        if (!CollectionUtil.isEmpty(deletePostIds)) {
            userPostMapper.deleteByUserIdAndPostId(userId, deletePostIds);
        }
    }

    @Override
    public void updateUserLogin(Long id, String loginIp) {
        userMapper.updateById(new AdminUserDO().setId(id).setLoginIp(loginIp).setLoginDate(LocalDateTime.now()));
    }

    @Override
    public void updateUserProfile(Long id, UserProfileUpdateReqVO reqVO) {
        // 校验正确性
        checkUserExists(id);
        checkEmailUnique(id, reqVO.getEmail());
        checkMobileUnique(id, reqVO.getMobile());
        // 执行更新
        userMapper.updateById(UserConvert.INSTANCE.convert(reqVO).setId(id));
    }

    @Override
    public void updateUserPassword(Long id, UserProfileUpdatePasswordReqVO reqVO) {
        String oldPassword = RSAUtils.decrypt(reqVO.getOldPassword());
        // 校验旧密码密码
        checkOldPassword(id, oldPassword);
        // 执行更新
        AdminUserDO updateObj = new AdminUserDO().setId(id);
        String newPassword = RSAUtils.decrypt(reqVO.getNewPassword());
        checkUserPassword(newPassword);

        List<String> shortdata = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get("password_update_five:" + id), List.class);
        List<String>  data = shortdata == null  ? new ArrayList<>() : shortdata ;

        if( data.size() <= 5){
            List<String> isExist =  data.stream().filter(e -> RSAUtils.decrypt(e).equals(newPassword)).collect(Collectors.toList());
            if(isExist.size()>0 ){
                throw exception(USER_FIVE_UPDATE_PASSWORD_FAILED);
            }else if(data.size()==0 &&  oldPassword.equals(newPassword)){ //
                data.add(reqVO.getNewPassword());
                throw exception(USER_FIVE_UPDATE_PASSWORD_FAILED);
            }
            data.add(reqVO.getNewPassword());
            stringRedisTemplate.opsForValue().set("password_update_five:"+id, JsonUtils.toJsonString(data));
        }else{
            List<String> isExist =  data.stream().filter(e -> data.indexOf(e) > 0 && RSAUtils.decrypt(e).equals(newPassword)).collect(Collectors.toList());
            if(isExist.size()>0 ){
                throw exception(USER_FIVE_UPDATE_PASSWORD_FAILED);
            }else {
                List<String> newCollect = data.stream().filter(e -> data.indexOf(e) > 0).collect(Collectors.toList());
                newCollect.add(reqVO.getNewPassword());
                stringRedisTemplate.opsForValue().set("password_update_five:"+id, JsonUtils.toJsonString(newCollect));
            }
        }
        updateObj.setPassword(encodePassword(newPassword)); // 加密密码
        userMapper.updateById(updateObj);
    }

    @Override
    public String updateUserAvatar(Long id, MultipartFile avatarFile) throws Exception {
        checkUserExists(id);
        // 存储文件
        String avatar = fileApi.createFile(avatarFile.getOriginalFilename(), null, IoUtil.readBytes(avatarFile.getInputStream()));
        // 更新路径
        AdminUserDO sysUserDO = new AdminUserDO();
        sysUserDO.setId(id);
        sysUserDO.setAvatar(avatar);
        userMapper.updateById(sysUserDO);
        return avatar;
    }

    @Override
    public void updateUserPassword(Long id, String password) {
        // admin 用户 只有自己可以修改
        checkAdminUser(id,null);
        // 校验用户存在
        checkUserExists(id);
        // 更新密码
        AdminUserDO updateObj = new AdminUserDO();
        updateObj.setId(id);
        String noEncodePassword = RSAUtils.decrypt(password);
        checkUserPassword(noEncodePassword);
        updateObj.setPassword(encodePassword(noEncodePassword)); // 加密密码
        userMapper.updateById(updateObj);
    }

    @Override
    public void updateUserStatus(Long id, Integer status) {
        // admin 用户 只有自己可以修改
        checkAdminUserStatus(id,status);
        // 校验用户存在
        checkUserExists(id);
        // 更新状态
        AdminUserDO updateObj = new AdminUserDO();
        updateObj.setId(id);
        updateObj.setStatus(status);
        userMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long id) {
        if(!String.valueOf(id).equals("1")){
            // 校验用户存在
            checkUserExists(id);
            // 删除用户
            userMapper.deleteById(id);
            // 删除用户关联数据
            permissionService.processUserDeleted(id);
            // 删除用户岗位
        }
    }

    @Override
    public AdminUserDO getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public AdminUserDO getUserByMobile(String mobile) {
        return userMapper.selectByMobile(mobile);
    }

    @Override
    public PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {
        return userMapper.selectPage(reqVO, getDeptCondition(reqVO.getDeptId()));
    }

    @Override
    public List<AdminUserDO> selectListAll() {
        return userMapper.selectListAll();
    }

    @Override
    public AdminUserDO getUser(Long id) {
        AdminUserDO adminUserDO = userMapper.selectById(id);
        if(adminUserDO != null && adminUserDO.getSex() != null && adminUserDO.getSex() == 0 ){
            adminUserDO.setSex(null);
        }
        return adminUserDO;
    }

    @Override
    public List<AdminUserDO> getUsersByDeptIds(Collection<Long> deptIds) {
        if (CollUtil.isEmpty(deptIds)) {
            return Collections.emptyList();
        }
        return userMapper.selectListByDeptIds(deptIds);
    }

    @Override
    public List<AdminUserDO> getUsersByPostIds(Collection<Long> postIds) {
        if (CollUtil.isEmpty(postIds)) {
            return Collections.emptyList();
        }
        Set<Long> userIds = convertSet(userPostMapper.selectListByPostIds(postIds), UserPostDO::getUserId);
        if (CollUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }
        return userMapper.selectBatchIds(userIds);
    }

    @Override
    public List<AdminUserDO> getUsers(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return userMapper.selectBatchIds(ids);
    }

    @Override
    public void validUsers(Set<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        // 获得岗位信息
        List<AdminUserDO> users = userMapper.selectBatchIds(ids);
        Map<Long, AdminUserDO> userMap = CollectionUtils.convertMap(users, AdminUserDO::getId);
        // 校验
        ids.forEach(id -> {
            AdminUserDO user = userMap.get(id);
            if (user == null) {
                throw exception(USER_NOT_EXISTS);
            }
            if (!CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus())) {
                throw exception(USER_IS_DISABLE, user.getNickname());
            }
        });
    }

    @Override
    public List<AdminUserDO> getUsers(UserExportReqVO reqVO) {
        return userMapper.selectList(reqVO, getDeptCondition(reqVO.getDeptId()));
    }

    @Override
    public List<AdminUserDO> getUsersByNickname(String nickname) {
        return userMapper.selectListByNickname(nickname);
    }

    @Override
    public List<AdminUserDO> getUsersByUsername(String username) {
        return userMapper.selectListByUsername(username);
    }

    @Override
    public List<AdminUserDO> selectList(Collection<String> names) {
        List<AdminUserDO> list = userMapper.selectList(new QueryWrapper<AdminUserDO>()
                .in("id", names)
        );
        return list;
    }

    @Override
    public List<AdminUserDO> selectListInner(List<Long> names) {
        List<AdminUserDO> list = userMapper.selectList(new QueryWrapper<AdminUserDO>()
                .in(names!=null && names.size()>0,"id", names)
        );
        return list;
    }

    /**
     * 获得部门条件：查询指定部门的子部门编号们，包括自身
     * @param deptId 部门编号
     * @return 部门编号集合
     */
    private Set<Long> getDeptCondition(Long deptId) {
        if (deptId == null) {
            return Collections.emptySet();
        }
        Set<Long> deptIds = convertSet(deptService.getDeptsByParentIdFromCache(
                deptId, true), DeptDO::getId);
        deptIds.add(deptId); // 包括自身
        return deptIds;
    }

    private void checkCreateOrUpdate(Long id, String username, String mobile, String email,
                                     Long deptId, Set<Long> postIds) {
        // 校验用户存在
        checkUserExists(id);
        // 校验用户名唯一
        checkUsernameUnique(id, username);
        // 校验手机号唯一
        checkMobileUnique(id, mobile);
        // 校验邮箱唯一
        checkEmailUnique(id, email);
        // 校验部门处于开启状态
        deptService.validDepts(CollectionUtils.singleton(deptId));
        // 校验岗位处于开启状态
        postService.validPosts(postIds);
    }

    @VisibleForTesting
    public void checkUserExists(Long id) {
        if (id == null) {
            return;
        }
        AdminUserDO user = userMapper.selectById(id);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }
    }

    @VisibleForTesting
    public void checkUserPassword(String password) {
        if (password == null) {
            return;
        }
        if (!match(password)) {
            throw exception(USER_PASSWORD_COMPLEXITY_FAILED);
        }
    }

    @VisibleForTesting
    @Override
    public void checkAdminUser(Long id,Integer status) {
        AdminUserDO adminUserDO = userMapper.selectById(id);
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if(!loginUser.getId().equals(id) && adminUserDO.getUsername().equals("admin")){
            throw exception(AUTH_ADMIN_PROVIDED);
        }

    }
    @VisibleForTesting
    @Override
    public void checkAdminUserStatus(Long id,Integer status) {
        AdminUserDO adminUserDO = userMapper.selectById(id);
        if(adminUserDO.getUsername().equals("admin") && status != null && status ==CommonStatusEnum.DISABLE.getStatus()){
            throw exception(AUTH_ADMIN_STATUS_DISABLED);
        }

    }

    @VisibleForTesting
    public void checkUsernameUnique(Long id, String username) {
        if (StrUtil.isBlank(username)) {
            return;
        }
        AdminUserDO user = userMapper.selectByUsername(username);
        if (user == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(USER_USERNAME_EXISTS);
        }
        if (!user.getId().equals(id)) {
            throw exception(USER_USERNAME_EXISTS);
        }
    }
    @Override
    @VisibleForTesting
    public   void checkUserNameRegexp(String username) {
        if(StringUtils.isBlank(username)){
            return;
        }
        if (!matchUsernameOne(username)) { // 登录账号由数字，字母，特殊字符!,@,#,$,%,^,&,*,（,）,_,+,=,组成
            throw exception(USER_USERNAME_VERIFY_ONE);
        }
        if (!matchUsernameTwo(username)) { // 登录账号需包含数字或字母一种
            throw exception(USER_USERNAME_VERIFY_TWO);
        }

    }

    @VisibleForTesting
    public void checkEmailUnique(Long id, String email) {
        if (StrUtil.isBlank(email)) {
            return;
        }
        AdminUserDO user = userMapper.selectByEmail(email);
        if (user == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(USER_EMAIL_EXISTS);
        }
        if (!user.getId().equals(id)) {
            throw exception(USER_EMAIL_EXISTS);
        }
    }

    @VisibleForTesting
    public void checkMobileUnique(Long id, String mobile) {
        if (StrUtil.isBlank(mobile)) {
            return;
        }
        AdminUserDO user = userMapper.selectByMobile(mobile);
        if (user == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(USER_MOBILE_EXISTS);
        }
        if (!user.getId().equals(id)) {
            throw exception(USER_MOBILE_EXISTS);
        }
    }

    /**
     * 校验旧密码
     * @param id          用户 id
     * @param oldPassword 旧密码
     */
    @VisibleForTesting
    public void checkOldPassword(Long id, String oldPassword) {
        AdminUserDO user = userMapper.selectById(id);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }
        if (!isPasswordMatch(oldPassword, user.getPassword())) {
            throw exception(USER_PASSWORD_FAILED);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务，异常则回滚所有导入
    public UserImportRespVO importUsers(MultipartFile file, boolean isUpdateSupport) {
        List<UserImportExcelVO> importUsers =null;
        try {
             importUsers = ExcelUtils.readUser(file, UserImportExcelVO.class);
        }catch (Exception e){
            throw exception(USER_IMPORT_TEMPLATE_CORRECT);
        }
        if (CollUtil.isEmpty(importUsers)) {
            throw exception(USER_IMPORT_LIST_IS_EMPTY);
        }
        UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
                .updateUsernames(new ArrayList<>()).failureUsernames(new ArrayList<>()).build();
        importUsers.forEach(importUser -> {
            if(StringUtils.isBlank(importUser.getUsername())){
                throw exception(USER_IMPORT_TEMPLATE_CORRECT);
            }
            //部门
            importUser.setDeptId(null);
            String deptName = importUser.getDeptName();
            if(StringUtils.isBlank(deptName)){
                importUser.setDeptId(0L);
            }else{
                if(deptName.contains("/")){
                    List<String> list = Arrays.asList(deptName.split("/"));
                    for (String deptNam : list) {
                        if(importUser.getDeptId() == null){
                            setDeptIdByImportUser(importUser,deptNam,null);
                        }else{
                            setDeptIdByImportUser(importUser,deptNam,importUser.getDeptId());
                        }
                    }
                }else{ //父节点
                    setDeptIdByImportUser(importUser,importUser.getDeptName(),null);
                }
            }
            // 岗位
            Set<Long> postIds = new HashSet<>();
            importUser.setPostIds(postIds);
            String postNames = importUser.getPostNames();
            if(StringUtils.isNoneBlank(postNames)){
                    List<String> list = Arrays.asList(postNames.split(","));
                    List<PostDO> postDOS = postMapper.selectList(new QueryWrapper<PostDO>()
                            .lambda().in(PostDO::getName, list)
                    );

                    if(postDOS!=null && postDOS.size()>0){
                        importUser.setPostIds(convertSet(postDOS,PostDO::getId));
                    }
            }

            // 校验账号是否符合规定  长度校验
            if (!usernameLengthMatch(importUser.getUsername())) {
                respVO.getFailureUsernames().add(new UserMsgRespVO(importUser.getUsername(), USER_USERNAME_VERIFY_EXISTS.getMsg()));
                return;
            }
            if (!matchUsernameOne(importUser.getUsername())) { // 登录账号由数字，字母，特殊字符!,@,#,$,%,^,&,*,（,）,_,+,=,组成
                respVO.getFailureUsernames().add(new UserMsgRespVO(importUser.getUsername(), USER_USERNAME_VERIFY_ONE.getMsg()));
                return;
            }
            if (!matchUsernameTwo(importUser.getUsername())) { // 登录账号需包含数字或字母一种
                respVO.getFailureUsernames().add(new UserMsgRespVO(importUser.getUsername(), USER_USERNAME_VERIFY_TWO.getMsg()));
                return;
            }
            if( importUser.getUsername().equals("admin")){
                respVO.getFailureUsernames().add(new UserMsgRespVO(importUser.getUsername(), AUTH_ADMIN_NOT_IMPORT.getMsg()));
                return;
            }
            // 校验，判断是否有不符合的原因
            try {
                AdminUserDO adminUserDO = userMapper.selectByUsername(importUser.getUsername());
                checkCreateOrUpdate(adminUserDO != null ? adminUserDO.getId() : null, null, importUser.getMobile(), importUser.getEmail(),
                        importUser.getDeptId(), null);
            } catch (ServiceException ex) {
                respVO.getFailureUsernames().add(new UserMsgRespVO(importUser.getUsername(), ex.getMessage()));
                return;
            }
            // 判断如果不存在，在进行插入
            AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
            if (existUser == null) {
                userMapper.insert(UserConvert.INSTANCE.convert(importUser)
                        .setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码
                respVO.getCreateUsernames().add(importUser.getUsername());
                return;
            }
            // 如果存在，判断是否允许更新
            if (!isUpdateSupport) {
                respVO.getFailureUsernames().add(new UserMsgRespVO(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg()));
                return;
            }
            AdminUserDO updateUser = UserConvert.INSTANCE.convert(importUser);
            updateUser.setId(existUser.getId());
            userMapper.updateById(updateUser);
            respVO.getUpdateUsernames().add(importUser.getUsername());
        });
        return respVO;
    }

    /**
     * 账户导入校验
     * @param
     * @return
        QueryWrapper<AdminUserDO> qw = new QueryWrapper<>();
        qw.lambda().in(AdminUserDO::getUsername, names);
        return userMapper.selectList(qw);
     */
    public static Boolean usernameLengthMatch(String username) {
        if(StringUtils.isBlank(username)){
            return false;
        }
        String rex = "^.{4,30}$";
        Pattern pattern = Pattern.compile(rex);
        Matcher matcher = pattern.matcher(username);
        return matcher.matches();
    }
    private void setDeptIdByImportUser(UserImportExcelVO importUser,String deptName ,Long deptId) {
        List<DeptDO> deptList = deptMapper.selectList(new QueryWrapper<DeptDO>()
                .eq("name", deptName)
                .eq(deptId != null,"parent_id",deptId)
        );
        if(deptList.size() != 1){
            importUser.setDeptId(0L);
        }else{
            importUser.setDeptId(deptList.get(0).getId());
        }

    }

    @Override
    public List<AdminUserDO> getUsersByStatus(Integer status) {
        return userMapper.selectListByStatus(status);
    }

    @Override
    public List<AdminUserDO> getUsersByRoleIds(Collection<Long> roleIds) {
        if (CollUtil.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        Set<Long> userIds = convertSet(userRoleMapper.selectListByRoleIds(roleIds), UserRoleDO::getUserId);
        if (CollUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }

        return userMapper.selectBatchIds(userIds);
    }

    @Override
    public boolean isPasswordMatch(String rawPassword, String encodedPassword) {
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    @Override
    public Collection<Object> getSessionKeys() {

        return webSocketSessionStore.getSessionKeys();
    }

    @Override
    public void distribute(MessageDO messageDO) {
        messageDistributor.distribute(messageDO);
    }

    @Override
    public List<String> selectData2(String sql) {
        return userMapper.selectData2(sql);
    }

    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        return passwordEncoder.encode(password);
    }

    /**
     *
     * @param password 密码
     * 正则校验密码，至少8个字符，至少1个大写字母，1个小写字母，1个数字和1个特殊字符
     * @return Boolean
     */
    public static Boolean match(String password) {
        String rex = "^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9_\\W]{8,}$";
        Pattern pattern = Pattern.compile(rex);
        Matcher matcher = pattern.matcher(password);
        return matcher.matches();
    }

    /**
     *  登录账号由数字，字母，特殊字符!,@,#,$,%,^,&,*,（,）,_,+,=,组成
     * @param username
     * @return
     */
    public static Boolean matchUsernameOne(String username) {
        String rex = "^[0-9a-zA-Z!@#$%^&*()_+=]{1,}$";
        Pattern pattern = Pattern.compile(rex);
        Matcher matcher = pattern.matcher(username);
        return matcher.matches();
    }

    /**
     * 登录账号需包含数字或字母一种
     * @param username
     * @return
     */
    public static Boolean matchUsernameTwo(String username) {
        String rex = ".*[0-9a-zA-Z]{1,}.*";
        Pattern pattern = Pattern.compile(rex);
        Matcher matcher = pattern.matcher(username);
        return matcher.matches();
    }

}
